/*
    * Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd.
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    *     http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
 */

#include "file_share_queue.h"

namespace OHOS {
namespace FileShare {
template <typename T>
int32_t FileShareQueue<T>::Pop(T &item)
{
    std::unique_lock<std::mutex> lock(mutex_);

    while (queue_.empty() && !isStoped_) {
        emptyCond_.wait(lock);
    }

    if (isStoped_) {
        return FS_QUEUE_STOPED;
    }

    if (queue_.empty()) {
        return FS_QUEUE_EMPTY;
    } else {
        item = queue_.front();
        queue_.pop_front();
    }

    fullCond_.notify_one();

    return FS_SUCCESS;
}

template <typename T>
int32_t FileShareQueue<T>::Push(const T& item, bool isWait)
{
    std::unique_lock<std::mutex> lock(mutex_);

    while (queue_.size() >= maxSize_ && isWait && !isStoped_) {
        fullCond_.wait(lock);
    }

    if (isStoped_) {
        return FS_QUEUE_STOPED;
    }

    if (queue_.size() >= maxSize_) {
        return FS_QUEUE_FULL;
    }
    queue_.push_back(item);

    emptyCond_.notify_one();

    return FS_SUCCESS;
}

template <typename T>
void FileShareQueue<T>::Stop()
{
    {
        std::unique_lock<std::mutex> lock(mutex_);
        isStoped_ = true;
    }

    fullCond_.notify_all();
    emptyCond_.notify_all();
}

template <typename T>
void FileShareQueue<T>::Restart()
{
    std::unique_lock<std::mutex> lock(mutex_);
    isStoped_ = false;
}

template <typename T>
size_t FileShareQueue<T>::GetSize()
{
    std::unique_lock<std::mutex> lock(mutex_);
    return queue_.size();
}

template <typename T>
bool FileShareQueue<T>::IsEmpty()
{
    std::unique_lock<std::mutex> lock(mutex_);
    return queue_.empty();
}

template <typename T>
void FileShareQueue<T>::Clear()
{
    std::unique_lock<std::mutex> lock(mutex_);
    queue_.clear();
}

template class FileShareQueue<SendTask>;
} // namespace FileShare
} // namespace OHOS